/**
 * Class: Sine
 *
 * Purpose: 
 *
 * Created: Jan 30, 2010 @ 10:26:20 AM
 * @author Ken Scott
 */
package org.openfantasia.musica.instruments;

import org.openfantasia.musica.Musica;
import org.openfantasia.util.Logger;
import net.beadsproject.beads.core.UGen;
import net.beadsproject.beads.events.KillTrigger;
import net.beadsproject.beads.ugens.Envelope;
import net.beadsproject.beads.ugens.Gain;
import net.beadsproject.beads.ugens.GranularSamplePlayer;

import javax.sound.sampled.UnsupportedAudioFileException;
import java.io.IOException;

public class Sample extends Instrument {

	private String path;

	private double baseFrequency = 0.0;

	private double duration;


	public Sample(Musica mc) {
		super(mc);
	}


	public Sample(Musica mc, String path) {
		this(mc);

		this.path = path;
		this.name = "Sample: " + path;
		net.beadsproject.beads.data.Sample sample = loadSample(path);
		sample.printAudioFormatInfo();
		duration = ((double) sample.getLength() * 1000000d) / mc.getNsPerTick();
		System.out.println(name + " Length = " + duration);
	}


	public Sample(Musica mc, String path, double baseFrequency) {
		this(mc, path);
		this.baseFrequency = baseFrequency;
	}


	public Sample(Musica mc, String path, String baseNote) {
		this(mc, path, mc.getToneFrequency(baseNote));
	}


	private net.beadsproject.beads.data.Sample loadSample(String path) {
		net.beadsproject.beads.data.Sample result = null;
		try {
			result = new net.beadsproject.beads.data.Sample(path, net.beadsproject.beads.data.Sample.Regime.newStreamingRegimeWithAging(1000, 500));
		}
		catch (IOException e) {
			Logger.error("Unable to load sample file: " + path, e);
		}
		catch (UnsupportedAudioFileException e) {
			Logger.error("Unable to read sample file: " + path, e);
		}
		return result;
	}


	public UGen getSound(double frequency) {
		GranularSamplePlayer result = new GranularSamplePlayer(musica.audioContext, loadSample(path));
		double ratio = (this.baseFrequency > 0) ? frequency / this.baseFrequency : 1.0;
		result.setPitchEnvelope(new Envelope(musica.audioContext, (float) ratio));
		return result;
	}


	public UGen getEnvelope(double volume, double durationNanos) {
		Gain result = musica.newGain(1, musica.newEnvelope(volume));
		((Envelope) result.getGainEnvelope()).addSegment(0, (float) durationNanos, new KillTrigger(result));
		return result;
	}


	public double getDuration() {
		return duration;
	}
}